import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { DiscordSnowflake } from "@sapphire/snowflake";
import { plainToInstance } from "class-transformer";
import { DataSource, Repository } from "typeorm";
import { ResultMsg } from "@/common/enum/result-msg.enum";
import Result from "@/common/utils/result.util";
import { SysCascaderItem } from "@/database/entity/SysCascaderItem";
import { SysCascaderType } from "@/database/entity/SysCascaderType";
import { CreateCascaderTypeDto } from "./dto/create-csdr-type.dto";
import { PageCascaderTypeDto } from "./dto/page-csdr-type.dto";
import { UpdateCascaderTypeDto } from "./dto/update-csdr-type.dto";
import { CascaderTypeDetailVo } from "./vo/csdr-type-detail.vo";
import { CascaderTypeListVo } from "./vo/csdr-type-list.vo";

@Injectable()
export class CascaderTypeService {
    constructor(
        @InjectRepository(SysCascaderType) private readonly cascaderTypeRepository: Repository<SysCascaderType>,
        private readonly dataSource: DataSource,
    ) {}

    /** 新增级联字典 */
    async create(data: CreateCascaderTypeDto) {
        const id = DiscordSnowflake.generate().toString();
        const entity = this.cascaderTypeRepository.create({ ...data, id });
        await this.cascaderTypeRepository.save(entity);
        return Result.success(id, ResultMsg.CREATE_SUCCESS);
    }

    /** 删除级联字典 */
    async remove(id: string) {
        await this.dataSource.transaction(async (manager) => {
            // 删除级联字典项
            await manager.update(SysCascaderItem, { typeId: id }, { deletedAt: new Date() });
            // 删除级联字典
            await manager.update(SysCascaderType, id, { deletedAt: new Date() });
        });
        return Result.success(null, ResultMsg.DELETE_SUCCESS);
    }

    /** 修改级联字典 */
    async update(data: UpdateCascaderTypeDto) {
        await this.cascaderTypeRepository.update(data.id, { ...data });
        return Result.success(null, ResultMsg.UPDATE_SUCCESS);
    }

    /** 根据 id 查询级联字典 */
    async findById(id: string): Promise<Result<CascaderTypeDetailVo>> {
        const record = await this.cascaderTypeRepository.findOne({
            select: ["id", "name", "code", "remark"],
            where: { id },
        });
        const detailVo = plainToInstance(CascaderTypeDetailVo, record, { excludeExtraneousValues: true });
        return Result.success(detailVo);
    }

    /** 分页查询级联字典 */
    async page(data: PageCascaderTypeDto): Promise<Result<CascaderTypeListVo[]>> {
        const { name, code, pageNum, pageSize } = data;
        const queryBuilder = this.cascaderTypeRepository.createQueryBuilder("ct");
        queryBuilder.select(["ct.id", "ct.name", "ct.code"]);

        if (name) {
            queryBuilder.andWhere("ct.name LIKE :name", { name: `%${name}%` });
        }
        if (code) {
            queryBuilder.andWhere("ct.code LIKE :code", { code: `%${code}%` });
        }

        queryBuilder
            .orderBy("ct.createdAt", "DESC")
            .skip((pageNum - 1) * pageSize)
            .take(pageSize);

        const [list, total] = await queryBuilder.getManyAndCount();
        const voList = plainToInstance(CascaderTypeListVo, list, { excludeExtraneousValues: true });
        return Result.page(voList, { pageNum, pageSize, total });
    }
}
